package service

import (
	"wms/internal/model"
	"wms/internal/model/request"
	"wms/pkg/database"

	"gorm.io/gorm"
)

// RoleService 角色服务
type RoleService struct {
	db *gorm.DB
}

// NewRoleService 创建角色服务
func NewRoleService() *RoleService {
	return &RoleService{
		db: database.GetDB(),
	}
}

// CreateRole 创建角色
func (s *RoleService) CreateRole(req *request.RoleCreateRequest) error {
	role := &model.Role{
		Name:   req.Name,
		Code:   req.Code,
		Status: req.Status,
	}
	return s.db.Create(role).Error
}

// UpdateRole 更新角色
func (s *RoleService) UpdateRole(req *request.RoleUpdateRequest) error {
	return s.db.Model(&model.Role{}).Where("id = ?", req.ID).Updates(map[string]interface{}{
		"name":        req.Name,
		"code":        req.Code,
		"description": req.Description,
		"status":      req.Status,
	}).Error
}

// DeleteRole 删除角色
func (s *RoleService) DeleteRole(id uint) error {
	return s.db.Delete(&model.Role{}, id).Error
}

// GetRoleByID 获取角色
func (s *RoleService) GetRoleByID(id uint) (*model.Role, error) {
	var role model.Role
	err := s.db.First(&role, id).Error
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// ListRoles 获取角色列表
func (s *RoleService) ListRoles(req *request.RoleListRequest) ([]*model.Role, int64, error) {
	var roles []*model.Role
	var total int64

	query := s.db.Model(&model.Role{})

	if req.Keyword != "" {
		query = query.Where("name LIKE ? OR code LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	if req.Status != nil {
		query = query.Where("status = ?", *req.Status)
	}

	err := query.Count(&total).Error
	if err != nil {
		return nil, 0, err
	}

	err = query.Offset((req.GetPage() - 1) * req.GetPageSize()).Limit(req.GetPageSize()).Find(&roles).Error
	if err != nil {
		return nil, 0, err
	}

	return roles, total, nil
}

// GetRolePermissions 获取角色权限
func (s *RoleService) GetRolePermissions(roleID uint) ([]uint, error) {
	var menuIDs []uint
	err := s.db.Model(&model.RoleMenu{}).
		Where("role_id = ?", roleID).
		Pluck("menu_id", &menuIDs).
		Error
	if err != nil {
		return nil, err
	}
	return menuIDs, nil
}

// UpdateRolePermissions 更新角色权限
func (s *RoleService) UpdateRolePermissions(roleID uint, menuIDs []uint) error {
	// 开启事务
	return s.db.Transaction(func(tx *gorm.DB) error {
		// 删除原有权限
		if err := tx.Where("role_id = ?", roleID).Delete(&model.RoleMenu{}).Error; err != nil {
			return err
		}

		// 如果没有新的权限，直接返回
		if len(menuIDs) == 0 {
			return nil
		}

		// 去重，确保没有重复的menuID
		uniqueMenuIDs := make([]uint, 0)
		encountered := make(map[uint]bool)
		for _, menuID := range menuIDs {
			if !encountered[menuID] {
				encountered[menuID] = true
				uniqueMenuIDs = append(uniqueMenuIDs, menuID)
			}
		}

		// 批量插入新权限
		roleMenus := make([]model.RoleMenu, len(uniqueMenuIDs))
		for i, menuID := range uniqueMenuIDs {
			roleMenus[i] = model.RoleMenu{
				RoleID: roleID,
				MenuID: menuID,
			}
		}

		// 使用CreateInBatches分批创建，减少出错风险
		return tx.CreateInBatches(&roleMenus, 100).Error
	})
}
